#include"login_ui.h"



lv_obj_t *keyboard = NULL;

lv_obj_t *chat_scr = NULL;

lv_obj_t *msg_cont = NULL;

lv_obj_t *cont;

lv_obj_t *all_file_win;//文件显示的窗口

sem_t cur_user_friend_update;
sem_t friend_list_update;
sem_t logs_update;//本地聊天消息

int listflag = 0;
int com_flag = 0;       
int chat_show_flag = 0; //聊天的标志
int cur_friend_id = 0; //当前的好友id

char cur_tranfile_path[64] = {0}; //相对路径

//   文本框与键盘
void keyboard_event_cb(lv_event_t* e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t* target = lv_event_get_target(e);
    if(code == LV_EVENT_FOCUSED) //点击是文本框
    {
        lv_obj_clear_flag(keyboard, LV_OBJ_FLAG_HIDDEN);//清楚隐藏标志
        lv_keyboard_set_textarea(keyboard, target);//选中与键盘进行关联
    }

    //焦点失去，隐藏键盘
    if(code == LV_EVENT_DEFOCUSED) {
        lv_keyboard_set_textarea(keyboard, NULL);
        lv_obj_add_flag(keyboard, LV_OBJ_FLAG_HIDDEN);
    }
}

//消息框响应
void event_cb_msgbox(lv_event_t *e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t *target = lv_event_get_current_target(e);
    if(code == LV_EVENT_PRESSED)
    {
        if(lv_msgbox_get_active_btn(target) == 2)    /* 获取按钮索引 */
            lv_obj_add_flag(target, LV_OBJ_FLAG_HIDDEN);  /* 添加隐藏标志 */
    }
}

//关闭窗口
void close_win_event(lv_event_t *e) {
    lv_obj_t *win = lv_event_get_user_data(e);
    lv_obj_del(win); // 删除窗口
    win = NULL;
}

//手动关闭窗口
void close_win(lv_obj_t *win)
{
    lv_obj_del(win); // 删除窗口
    win = NULL;
}

//是否有该好友
int find_friend(unsigned int friend_id)
{
    for(int i=0;i<cur_friend_num;i++)
    {
        if(cur_user_friend[i].id == friend_id)
        {
            return 1;
        }
    }
    return 0;
}

//保存用户关系数据到文件
void save_user_friend_file(char *filename)
{
    FILE *fp = fopen(filename,"w");
    if(fp == NULL)
    {
        perror("fopen() fail");
        return;
    }
    for(int i=0;i<cur_friend_num;i++)
    {
        // printf("id:%u, name:%s\n",cur_user_friend[i].id,cur_user_friend[i].username);
        fwrite(&cur_user_friend[i],sizeof(friend),1,fp);
    }
    fclose(fp);
}

void first_save_user_friend_file(char *filename)
{
    FILE *fp = fopen(filename,"w");
    if(fp == NULL)
    {
        perror("fopen() fail");
        return;
    }
    for(int i=0;i<user_friend_num;i++)
    {
        printf("id:%u, name:%s\n",user_friend[i].id,user_friend[i].username);
        fwrite(&user_friend[i],sizeof(friend),1,fp);
    }
    fclose(fp);
    
}

//保存本地聊天记录 chatlog.txt
void save_user_chat_log_file(char *filename)
{
    FILE *fp = fopen(filename,"w");
    if(fp == NULL)
    {
        perror("fopen() fail");
        return;
    }
    for(int i=0;i<logs_num;i++)
    {
        // printf("sendid:%u, recvid:%u msg:%s\n",logs[i].sendid,logs[i].recvid,logs[i].msg);
        fwrite(&logs[i],sizeof(chat_log),1,fp);
    }
    fclose(fp);
}

//添加好友的响应
void add_friend_event_cb(lv_event_t *e)
{
    lv_obj_t *userid_ta = lv_event_get_user_data(e);

    //获取要添加的好友id
    char *friend_id_s = lv_textarea_get_text(userid_ta);
    int friend_id = atoi(friend_id_s); 

    if(friend_id == cur_user.id)
    {
        printf("不能添加自己\n");
        static const char *msgbtn[] = {" "," ","OK",""};
        lv_obj_t *msgbox = lv_msgbox_create(lv_scr_act(),LV_SYMBOL_WARNING"Notice","Cannot add oneself",msgbtn,true);
        lv_obj_set_size(msgbox,350,130);
        lv_obj_align(msgbox,LV_ALIGN_CENTER,0,0);
        lv_obj_t* btn = lv_msgbox_get_btns(msgbox);
        lv_obj_set_style_bg_opa(btn, 0, LV_PART_ITEMS);    //背景透明
        lv_obj_set_style_shadow_width(btn, 0, LV_PART_ITEMS);    //去除阴影
        lv_obj_set_style_text_color(btn, lv_color_hex(0x0000ff),LV_PART_ITEMS);    //字体颜色
        lv_obj_add_event_cb(msgbox, event_cb_msgbox, LV_EVENT_PRESSED,NULL);
        return;
    }

    if(find_friend(friend_id))
    {
        printf("已经有该好友\n");
        static const char *msgbtn[] = {" "," ","OK",""};
        lv_obj_t *msgbox = lv_msgbox_create(lv_scr_act(),LV_SYMBOL_WARNING"Notice","This friend has already been added.",msgbtn,true);
        lv_obj_set_size(msgbox,350,130);
        lv_obj_align(msgbox,LV_ALIGN_CENTER,0,0);
        lv_obj_t* btn = lv_msgbox_get_btns(msgbox);
        lv_obj_set_style_bg_opa(btn, 0, LV_PART_ITEMS);    //背景透明
        lv_obj_set_style_shadow_width(btn, 0, LV_PART_ITEMS);    //去除阴影
        lv_obj_set_style_text_color(btn, lv_color_hex(0x0000ff),LV_PART_ITEMS);    //字体颜色
        lv_obj_add_event_cb(msgbox, event_cb_msgbox, LV_EVENT_PRESSED,NULL);
        return;
    }
    //拼接申请好友的数据type:recvid:msg
    char msg[32];
    bzero(msg,32);
    
    sprintf(msg,"2:%d:request",friend_id);

    write(comfd,msg,strlen(msg));

}

//添加好友的窗口
void add_friend_windows(lv_event_t *e)
{
    //创建一个模态背景窗口
    lv_obj_t *add_friend_win = lv_win_create(lv_scr_act(), 50);
    lv_obj_set_size(add_friend_win, 800, 480);
    lv_obj_center(add_friend_win);
    lv_win_add_title(add_friend_win, "Add-friend");
    // 关闭标志
    lv_obj_t *close_btn = lv_win_add_btn(add_friend_win, LV_SYMBOL_CLOSE, 50);
    lv_obj_add_event_cb(close_btn, close_win_event, LV_EVENT_CLICKED, add_friend_win);

    //添加好友界面
    lv_obj_t *add_friend_scr = lv_obj_create(add_friend_win);
    lv_obj_set_size(add_friend_scr,800,430);
    lv_obj_set_style_border_width(add_friend_scr, 0, 0);
    lv_obj_set_style_pad_all(add_friend_scr, 0, 0);

    //键盘
    keyboard = lv_keyboard_create(lv_scr_act());
    lv_keyboard_set_textarea(keyboard, NULL);
    lv_obj_add_flag(keyboard, LV_OBJ_FLAG_HIDDEN);

    //文本:用于输入要添加用户的id
    lv_obj_t *add_friend_ta = lv_textarea_create(add_friend_scr);
    lv_obj_set_size(add_friend_ta, 300, 50);
    lv_obj_align(add_friend_ta, LV_ALIGN_TOP_MID, 0, 50);
    lv_obj_remove_style(add_friend_ta, NULL, LV_PART_SCROLLBAR);    //移除滚动条样式
    lv_textarea_set_placeholder_text(add_friend_ta, "Friend Id");//占位符的内容
    lv_obj_add_event_cb(add_friend_ta, keyboard_event_cb, LV_EVENT_ALL,NULL);//键盘

    //添加按钮
    lv_obj_t * add_friend_btn = lv_btn_create(add_friend_scr);
    lv_obj_set_size(add_friend_btn,100,40);
    lv_obj_set_style_border_width(add_friend_btn, 0, 0);
    lv_obj_set_style_pad_all(add_friend_btn, 0, 0);
    lv_obj_align(add_friend_btn,LV_ALIGN_TOP_MID,0,150);
    lv_obj_add_event_cb(add_friend_btn,add_friend_event_cb,LV_EVENT_CLICKED,add_friend_ta);

    lv_obj_t *add_friend_label =  lv_label_create(add_friend_btn);
    lv_label_set_text(add_friend_label,"add");
    lv_obj_center(add_friend_label);    
}

//动态刷新当前用户的好友数量
void *refresh_friend_list(void* arg)
{
    sleep(1);
    while(1)
    {
        FILE *fp = fopen("friend.txt","r");
        if(fp == NULL)
        {
            perror("file_load_data fail");
            return ;
        }
        friend tmp;
        //从文件读取好友信息
        while(fread(&tmp ,sizeof(friend),1,fp) == 1)
        {
            if(tmp.cur_id == cur_user.id)
            {
                cur_user_friend[cur_friend_num] = tmp;
                printf("好友id:%u    name:%s\n",cur_user_friend[cur_friend_num].id,cur_user_friend[cur_friend_num].username);
                cur_friend_num++;
            }
        }
        fclose(fp);
        printf("refresh_f:%d\n",cur_friend_num);
        sem_post(&friend_list_update);//更新好友列表
        sem_wait(&cur_user_friend_update);
        bzero(cur_user_friend,cur_friend_num);
        cur_friend_num = 0;
    }
}

//动态加载本地消息
void *refresh_chat_log(void *arg)
{
    while(1)
    {
        FILE *fp = fopen("chatlog.txt","r");
        if(fp == NULL)
        {
            perror("file_load_data fail");
            return ;
        }
        chat_log log;
        //从文件读取好友信息
        while(fread(&log ,sizeof(chat_log),1,fp) == 1)
        {
            logs[logs_num] = log;
            logs_num++;
        }
        fclose(fp);
        sem_wait(&logs_update);
        // bzero(logs,logs_num);
        logs_num = 0;
        printf("刷新本地消息\n");
    }
}

//接收OOB数据
void recvOOB(int sig)
{
    char oob;
    recv(comfd, &oob, 1, MSG_OOB); //接收对端的OOB带外数据
	printf("指定的ID不存在,或对方已下线。\n");
}

//好友申请确认框
void msgbox_event_handler(lv_event_t *e)
{
    lv_obj_t *target = lv_event_get_current_target(e);
    char *msg = (char*)lv_event_get_user_data(e);
    char *type = strtok(msg,":");
    char *sendid_s = strtok(NULL,":");
    int sid = atoi(sendid_s);
    char *sendname = strtok(NULL,":");
    // 获取用户点击的按钮文本
    char btn_txt[32];
    char buf[256];
    bzero(btn_txt,32);
    bzero(buf,256);
    strcpy(btn_txt,lv_msgbox_get_active_btn_text(target));

    if (strcmp(btn_txt, "Yes") == 0) {
        //更新好友数组，更新好友文件
        // buf类型:type:sendid:sendname:recvid:msg:size
        friend f_new ;
        f_new.cur_id =cur_user.id;
        f_new.id = (unsigned int)sid;
        strcpy(f_new.username,sendname);
        cur_user_friend[cur_friend_num++] = f_new;
        //加载好友文件
        save_user_friend_file("friend.txt");
        //返回同意消息
        
        sprintf(buf,"2:%d:yes",sid);
        write(comfd,buf,strlen(buf));
        sem_post(&cur_user_friend_update);//更新当前用户的好友信息
        //返回聊天界面
        qq_ui_init();
    }else if(strcmp(btn_txt,"No") == 0)
    {
        sprintf(buf,"2:%d:no",sid);
        write(comfd,buf,strlen(buf));
    }

    // 关闭消息框
    lv_msgbox_close(target);
}

//文件是否接收申请框
void msgbox_file_recv(lv_event_t *e)
{
    //type:sendid:sendname:recvid:msg:size
    lv_obj_t *target = lv_event_get_current_target(e);
    char *msg = (char*)lv_event_get_user_data(e);  
    char *type = strtok(msg,":"); 
    char *sendid_s = strtok(NULL,":");
    int sid = atoi(sendid_s);
    char *sendname = strtok(NULL,":");

    char *recvid = strtok(NULL,":");
    char *filename = strtok(NULL,":");
    // 获取用户点击的按钮文本
    char btn_txt[32];
    char buf[256];
    bzero(btn_txt,32);
    bzero(buf,256);
    strcpy(btn_txt,lv_msgbox_get_active_btn_text(target));

    if (strcmp(btn_txt, "Yes") == 0) {
        //更新好友数组，更新好友文件
        // buf类型:type:sendid:sendname:recvid:msg:size
        //返回同意消息type:id:message:size
        sprintf(buf,"1:%d:%s:-1",sid,filename); //-1同意接收

        //创建文件	`O_WRONLY	O_CREAT	O_TRUNC`文件不存在则创建，存在则清空
        int fd = open(filename,O_WRONLY | O_CREAT | O_TRUNC,0666);
        if(fd < 0)
        {
            perror("open failed");  // 打印错误信息（如权限不足）
            return 1;
        }
        close(fd);

        write(comfd,buf,strlen(buf));

    }else if(strcmp(btn_txt,"No") == 0)
    {
        sprintf(buf,"1:%d:%s:-2",sid,filename); //-2拒绝接收
        write(comfd,buf,strlen(buf));
    }

    // 关闭消息框
    lv_msgbox_close(target);
}

//刷新聊天框
void update_msg(void)
{
    if(cur_friend_id == 0)
    {
        return;
    }
    printf("12\n");
    //清空聊天的内容
    lv_obj_clean(msg_cont);
    msg_cont = NULL; 
    msg_cont = lv_obj_create(cont);
    lv_obj_set_size(msg_cont, 600, 270);
    lv_obj_set_style_border_width(msg_cont, 0, 0);
    lv_obj_set_style_pad_all(msg_cont, 0, 0);
    lv_obj_set_style_bg_color(msg_cont, lv_color_make(160,225 , 253), LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_align(msg_cont,LV_ALIGN_TOP_MID,0,30);

    printf("12\n");
    lv_obj_set_flex_flow(msg_cont, LV_FLEX_FLOW_COLUMN);
    int num = 0;
    usleep(3*1000);
    for(int i=0;i<logs_num;i++)
    {
        if(logs[i].sendid == cur_user.id && logs[i].recvid == (unsigned int)cur_friend_id)
        {
            //放在右边
            //创建一个消息容器
            lv_obj_t *msg_big_cont = lv_obj_create(msg_cont);
            lv_obj_set_size(msg_big_cont,600,50);
            lv_obj_set_style_border_width(msg_big_cont, 0, 0);
            lv_obj_set_style_pad_all(msg_big_cont, 0, 0);
            lv_obj_set_style_bg_color(msg_big_cont, lv_color_make(160,225 , 253), LV_PART_MAIN | LV_STATE_DEFAULT);
            // lv_obj_set_style_bg_color(msg_big_cont, lv_color_make(0,255 , 0), LV_PART_MAIN | LV_STATE_DEFAULT);

            lv_obj_t *msg_small_cont = lv_obj_create(msg_big_cont);
            lv_obj_set_size(msg_small_cont,300,50);
            lv_obj_set_style_border_width(msg_small_cont, 0, 0);
            lv_obj_set_style_pad_all(msg_small_cont, 0, 0);
            lv_obj_set_style_bg_color(msg_small_cont, lv_color_make(254,215 , 255), LV_PART_MAIN | LV_STATE_DEFAULT);
            lv_obj_set_align(msg_small_cont,LV_ALIGN_RIGHT_MID);

            //创建lable用于存放消息
            lv_obj_t *label = lv_label_create(msg_small_cont);
            lv_label_set_text(label,logs[i].msg);
            lv_obj_align(label,LV_ALIGN_RIGHT_MID,-10,0);
            num++;
        }
        else if(logs[i].recvid == cur_user.id && logs[i].sendid == ((unsigned int)cur_friend_id))
        {
            //放在左边
            //创建一个消息容器
            lv_obj_t *msg_big_cont = lv_obj_create(msg_cont);
            lv_obj_set_size(msg_big_cont,600,50);
            lv_obj_set_style_border_width(msg_big_cont, 0, 0);
            lv_obj_set_style_pad_all(msg_big_cont, 0, 0);
            lv_obj_set_style_bg_color(msg_big_cont, lv_color_make(160,225 , 253), LV_PART_MAIN | LV_STATE_DEFAULT);


            lv_obj_t *msg_small_cont = lv_obj_create(msg_big_cont);
            lv_obj_set_size(msg_small_cont,300,50);
            lv_obj_set_style_border_width(msg_small_cont, 0, 0);
            lv_obj_set_style_pad_all(msg_small_cont, 0, 0);
            lv_obj_set_style_bg_color(msg_small_cont, lv_color_make(183,251 , 168), LV_PART_MAIN | LV_STATE_DEFAULT);

            lv_obj_set_align(msg_small_cont,LV_ALIGN_LEFT_MID);
            //创建lable用于存放消息
            lv_obj_t *label = lv_label_create(msg_small_cont);
            lv_label_set_text(label,logs[i].msg);
            lv_obj_align(label,LV_ALIGN_LEFT_MID,10,0);
            num++;
        }
        // printf("num:%d\n",num);
    }
    printf("num=%d\n",num);
    int y = ((270-num*70) > 0) ? 0 : (num*70-270);
    printf("y = %d\n",y);
    lv_obj_scroll_to_y(msg_cont,y+50, LV_ANIM_ON);//滚动到底部
    printf("滚动\n");
}

//recvMsg:接收消息
void *recvMsg(void *arg)
{
    int nread;
    char *buf = calloc(1,1024);
    char type[2];  //接收的消息类型: 0:普通消息 1:文件 2:好友申请或回应 
    char msg[1024];
    
    while(1)
    {
        bzero(buf,1024);
        bzero(type,2);
        bzero(msg,1024);
        nread = read(comfd,buf,1024);
        //buf类型:type:sendid:sendname:recvid:msg:size
        if(nread == -1)
		{
			perror("读取网络数据失败");
			break;
		}
		if(nread == 0)
		{
			printf("对端已关闭\n");
			exit(0);
		}
        printf("buf= %s\n",buf);
        char all_msg[1024];
        strcpy(all_msg,buf);//提取复制整条消息

        strcpy(type,strtok(buf,":"));

        char *sendid_s = strtok(NULL,":");//发送者
        int sendid = atoi(sendid_s);

        char *sendname = strtok(NULL,":");//发送者名称

        char *recvid = strtok(NULL,":");//接收者
        int recvidi = atoi(recvid);

        char *msg = strtok(NULL,":"); //信息(文件名)
        if(strcmp(type,"-1") == 0)
        {
            printf("更新好友信息\n");
            printf("sendid = %d\n",sendid);
            if(sendid == 0)
            {
                first_save_user_friend_file("friend.txt");
            }else{
                printf("更新\n");
                friend f;
                f.cur_id = cur_user.id;
                f.id = sendid;
                strcpy(f.username,sendname);
                // cur_user_friend[user_friend_num++] = f;
                user_friend[user_friend_num++] = f;
                //更新friend.txt
                first_save_user_friend_file("friend.txt");

            }
            sem_post(&cur_user_friend_update);//当前用户的好友
            // sem_post(&friend_list_update);//更新好友列表(全部的好友)
            
        }
        else if(strcmp(type,"0") == 0)
        {
            //接收普通消息
            //保存到消息中
            printf("all_msg:%s\n",all_msg);
            chat_log cl ;
            cl.sendid = (unsigned int)sendid;
            cl.recvid = (unsigned int)recvidi;
            strcpy(cl.msg,msg);

            logs[logs_num++] = cl;

            //保存到本地文件中
            save_user_chat_log_file("chatlog.txt");
            //获得资源:刷新本地聊天库
            sem_post(&logs_update);
            if(cl.sendid == cur_friend_id)
            {
                usleep(1000);
                update_msg();
            }
        }
        else if(strcmp(type,"1") == 0)   //文件
        {
            char *size = strtok(NULL,":"); //大小
            int fsize = atoi(size); 
            //文件type:sendid:sendname:recvid:msg:size:
            if(fsize == 0)
            {
                //是否接收
                char txt[256];
                bzero(txt,256);
                sprintf(txt,"%s have sent you the file %s",sendid_s,msg);
                static const char *btns[]  = {"Yes","No",""};
          
                printf("all_msg = %s\n",all_msg);
                lv_obj_t * mbox = lv_msgbox_create(NULL, "Confirm", txt, btns, true);
                lv_obj_center(mbox);
                lv_obj_add_event_cb(mbox, msgbox_file_recv, LV_EVENT_VALUE_CHANGED, (void *)all_msg);
                // 居中显示消息框
                lv_obj_center(mbox);
            }else if(fsize == -1){  //同意接受
                //准备发送 msg是文件名
                int fd = open(cur_file.filepath,O_RDONLY);
                if(fd < 0)
                {
                    perror("open fail");
                    return;
                }
                int nread_file;
                char filebuf[1024];
                while(1)
                {
                    bzero(filebuf,1024);
                    nread_file = read(fd,filebuf,1024);

                    if(nread_file == 0)
                    {
                        break;
                    }
                    //拼接发送type:id:message:size:filetext
                    char Msg[4096];
                    sprintf(Msg,"1:%d:%s:%d:%s",sendid,msg,nread_file,filebuf);
                    write(comfd,Msg,strlen(Msg));
                }

                close(fd);

            }else if(fsize == -2)
            {
                //拒绝接收，//取消发送
            }else if(fsize > 0)
            {
                char *filetext = strtok(NULL,":");
                //接收文件
                int fd = open(msg,O_WRONLY | O_APPEND | O_CREAT,0666);
                if (fd == -1) {
                    perror("open 失败");
                    return ;
                }
                
                write(fd,filetext,strlen(filetext));

                close(fd);
            }
        }
        else if(strcmp(type,"2") == 0)
        {

            //好友申请的消息 yes:同意 no:拒绝 request:申请
            if(strcmp(msg,"request") == 0) //发送一条好友申请
            {
                printf("request\n");
                char txt[256];
                bzero(txt,256);
                sprintf(txt,"%s apply to be added as a friend",sendid_s);
                static const char *btns[]  = {"Yes","No",""};
          
                printf("all_msg = %s\n",all_msg);
                lv_obj_t * mbox = lv_msgbox_create(NULL, "Confirm", txt, btns, true);
                lv_obj_center(mbox);
                lv_obj_add_event_cb(mbox, msgbox_event_handler, LV_EVENT_VALUE_CHANGED, (void *)all_msg);
                // 居中显示消息框
                lv_obj_center(mbox);
            }
            else if(strcmp(msg,"yes") == 0)
            {
                //内部添加改发送者好友
                friend new;
                new.cur_id = cur_user.id;
                new.id = (unsigned int)sendid;
                strcpy(new.username,sendname);
                cur_user_friend[cur_friend_num++] = new;
                //加载好友文件
                save_user_friend_file("friend.txt");
                // sem_post(&friend_list_update);//更新好友列表(全部的好友)
                sem_post(&cur_user_friend_update);//更新当前用户的好友信息
                static const char *msgbtn[] = {" "," ","OK",""};
                lv_obj_t *msgbox = lv_msgbox_create(lv_scr_act(),LV_SYMBOL_WARNING"Notice","Successfully added as a friend",msgbtn,true);
                lv_obj_set_size(msgbox,350,130);
                lv_obj_align(msgbox,LV_ALIGN_CENTER,0,0);
                lv_obj_t* btn = lv_msgbox_get_btns(msgbox);
                lv_obj_set_style_bg_opa(btn, 0, LV_PART_ITEMS);    //背景透明
                lv_obj_set_style_shadow_width(btn, 0, LV_PART_ITEMS);    //去除阴影
                lv_obj_set_style_text_color(btn, lv_color_hex(0x0000ff),LV_PART_ITEMS);    //字体颜色
                lv_obj_add_event_cb(msgbox, event_cb_msgbox, LV_EVENT_PRESSED,NULL);

            }
            else if(strcmp(msg,"no") == 0)
            {
                //对方拒绝加你为好友
                printf("The other party rejected your application\n");
                static const char *msgbtn[] = {" "," ","OK",""};
                lv_obj_t *msgbox = lv_msgbox_create(lv_scr_act(),LV_SYMBOL_WARNING"Notice","The other party rejected your application",msgbtn,true);
                lv_obj_set_size(msgbox,350,130);
                lv_obj_align(msgbox,LV_ALIGN_CENTER,0,0);
                lv_obj_t* btn = lv_msgbox_get_btns(msgbox);
                lv_obj_set_style_bg_opa(btn, 0, LV_PART_ITEMS);    //背景透明
                lv_obj_set_style_shadow_width(btn, 0, LV_PART_ITEMS);    //去除阴影
                lv_obj_set_style_text_color(btn, lv_color_hex(0x0000ff),LV_PART_ITEMS);    //字体颜色
                lv_obj_add_event_cb(msgbox, event_cb_msgbox, LV_EVENT_PRESSED,NULL);
                
            }
            
        }
    }
}

//从本地获得文件以及文件路径
int load_fileinfo(char *dir_path)
{
    struct dirent *ep;
    struct stat stat_buf;
    //打开目录获取目录指针
    DIR *dp = opendir(dir_path);
    if(dp == NULL)
    {
        fprintf(stderr,"opendir() fail :%s \n",strerror(errno));
        return -1;
    }
     while((ep = readdir(dp))!= NULL)
    {
        //忽略隐藏文件
        if(strncmp(ep->d_name,".",1) == 0)
        {
            continue;
        }
        //构建完整路径(使用安全格式化函数)
        char src_full[4096];
        snprintf(src_full,4096,"%s/%s",dir_path,ep->d_name);
        // printf("file_path:%s\n",src_full);
        //获取文件属性
        if(lstat(src_full,&stat_buf) == -1)
        {
            perror("获取文件属性失败");
            return -1;
        }

        //根据文件类型分发处理逻辑
        switch(stat_buf.st_mode & S_IFMT)
        {
            case S_IFREG:    //普通文件
                if(file_num < MAX_FILE_NUM && ep->d_type == DT_REG && stat_buf.st_size != 0)
                {
                    // strncpy(filenames[currlen++],src_full,256);
                    fileinfo file;
                    strcpy(file.filename,ep->d_name);//文件名称
                    strcpy(file.filepath,src_full);//文件路径
                    file.filesize = stat_buf.st_size;//文件大小
                    files[file_num++] = file;
                }
                break;
            case S_IFDIR:    //子目录
                if((load_fileinfo(src_full)) == -1)
                {
                    closedir(dp);
                }
                break;
            default:
                fprintf(stderr,"WARN:跳过特殊文件:%s\n",src_full);
                break;
        }

    }

        //关闭文件指针
    closedir(dp);
    return file_num;
}

//查找文件
fileinfo find_fileinfo(char *filepath)
{
    fileinfo file;
    for(int i=0;i<file_num;i++)
    {
        if(strcmp(files[i].filepath,filepath) == 0)
        {
            file = files[i];
            return file;
        }
    }
    return file;
}

//选择文件按钮的响应
void file_btn_event_cb(lv_event_t *e)
{
    lv_obj_t *target = lv_event_get_target(e);

    //获得输入框的对象
    lv_obj_t *ta = lv_event_get_user_data(e);
    //获得文件按钮上的label的内容
    lv_obj_t *label = lv_obj_get_child(target,0);
    char *txt = lv_label_get_text(label);
    printf("txt:%s\n",txt);

    //将内容设置在ta上
    char buf[256];
    sprintf(buf,"%s:%s",LV_SYMBOL_DIRECTORY,txt);
    printf("buf:%s\n",buf);

    lv_textarea_set_text(ta,buf);

    cur_file = find_fileinfo(txt);


    close_win(all_file_win);

}

//显示所有文件
void file_event_cb(lv_event_t *e)
{
    lv_obj_t *ta = lv_event_get_user_data(e); //文本框

    //建个窗口，显示当前的所有文件，以及一个文本框
    //创建一个模态背景窗口
    all_file_win = lv_win_create(lv_scr_act(), 50);
    lv_obj_set_size(all_file_win, 800, 480);
    lv_obj_center(all_file_win);
    lv_win_add_title(all_file_win, "Select-file");
    // 关闭标志
    lv_obj_t *close_btn = lv_win_add_btn(all_file_win, LV_SYMBOL_CLOSE, 50);
    lv_obj_add_event_cb(close_btn, close_win_event, LV_EVENT_CLICKED, all_file_win);

    //显示好友界面
    lv_obj_t *all_file_scr = lv_obj_create(all_file_win);
    lv_obj_set_size(all_file_scr,800,430);
    lv_obj_set_style_border_width(all_file_scr, 0, 0);
    lv_obj_set_style_pad_all(all_file_scr, 0, 0);

    //键盘
    keyboard = lv_keyboard_create(lv_scr_act());
    lv_keyboard_set_textarea(keyboard, NULL);
    lv_obj_add_flag(keyboard, LV_OBJ_FLAG_HIDDEN);

    //文本:用于输入要传递的文件名称
    lv_obj_t *add_file_ta = lv_textarea_create(all_file_scr);
    lv_obj_set_size(add_file_ta, 200, 50);
    lv_obj_align(add_file_ta, LV_ALIGN_TOP_MID, -50, 10);
    lv_obj_remove_style(add_file_ta, NULL, LV_PART_SCROLLBAR);    //移除滚动条样式
    lv_textarea_set_placeholder_text(add_file_ta, "file name");//占位符的内容
    lv_obj_add_event_cb(add_file_ta, keyboard_event_cb, LV_EVENT_ALL,NULL);//键盘

    //添加按钮
    lv_obj_t * add_file_btn = lv_btn_create(all_file_scr);
    lv_obj_set_size(add_file_btn,80,40);
    lv_obj_set_style_border_width(add_file_btn, 0, 0);
    lv_obj_set_style_pad_all(add_file_btn, 0, 0);
    lv_obj_align(add_file_btn,LV_ALIGN_TOP_MID,110,15);
    // lv_obj_add_event_cb(add_file_btn,add_file_event_cb,LV_EVENT_CLICKED,add_file_ta);

    lv_obj_t *add_file_label =  lv_label_create(add_file_btn);
    lv_label_set_text(add_file_label,"select");
    lv_obj_center(add_file_label); 


    //获得当前目录下所有的文件
    load_fileinfo(".");
    //显示当前目录下所有的文件的容器
    lv_obj_t *file_cont = lv_obj_create(all_file_scr);
    lv_obj_set_size(file_cont,800,350);
    lv_obj_set_style_border_width(all_file_scr, 0, 0);
    lv_obj_set_style_pad_all(all_file_scr, 0, 0);
    lv_obj_align(file_cont, LV_ALIGN_BOTTOM_MID, 0,0);
    lv_obj_set_flex_flow(file_cont, LV_FLEX_FLOW_ROW_WRAP);  // 自动换行

    //添加文件按钮
    for(int i=0;i<file_num;i++)
    {
        lv_obj_t *btn = lv_btn_create(file_cont);
        lv_obj_set_size(btn, 350, 60);
        lv_obj_set_style_border_width(btn, 0, 0);
        lv_obj_set_style_pad_all(btn, 0, 0);

        lv_obj_t *label = lv_label_create(btn);
        lv_label_set_text(label, files[i].filepath);
        lv_obj_center(label);

        lv_obj_add_event_cb(btn, file_btn_event_cb, LV_EVENT_CLICKED, (void*)ta);
    }
}

//发送的响应
void send_event_cb(lv_event_t *e)
{
    //文本框
    lv_obj_t *ta = lv_event_get_user_data(e);
    //获得文本框的内容
    char *txt = lv_textarea_get_text(ta);

    char all_txt[256];
    strcpy(all_txt,txt);
    printf("txt:%s\n",txt);

    //判断是否为文件 如果是文件则开头为LV_SYMBOL_DIRECTORY
    if(strstr(txt,LV_SYMBOL_DIRECTORY) != NULL)
    {
        //文件的发送
        printf("send file\n");
        char msg[1024];
        char *dir = strtok(txt,":");
        char *filename = strtok(NULL,":");

        //size为0则表示告诉对方要发什么文件：提前创建好，或者拒绝接收
        sprintf(msg,"1:%d:%s:0",cur_friend_id,filename);
        printf("msg:%s\n",msg);
        write(comfd,msg,strlen(msg));

        //保存到本地消息中
        chat_log cl ;
        cl.sendid = cur_user.id;
        cl.recvid = (unsigned int)cur_friend_id;
        strcpy(cl.msg,all_txt);

        logs[logs_num++] = cl;

        //保存到本地消息文件中
        save_user_chat_log_file("chatlog.txt");
        //获得资源:刷新本地聊天库
        sem_post(&logs_update);
    }else{
        //普通信息
        //拼接：type:recvid:msg
        char msg[256];
        sprintf(msg,"0:%d:%s",cur_friend_id,txt);
        // printf("msg:%s\n",msg);
        //发送
        write(comfd,msg,strlen(msg));

        //保存到本地消息中
        chat_log cl ;
        cl.sendid = cur_user.id;
        cl.recvid = (unsigned int)cur_friend_id;
        strcpy(cl.msg,txt);

        logs[logs_num++] = cl;

        //保存到本地消息文件中
        save_user_chat_log_file("chatlog.txt");
        //获得资源:刷新本地聊天库
        sem_post(&logs_update);

        usleep(3*1000);
        update_msg();
    }
    lv_textarea_set_text(ta, ""); 
}

//一个人的聊天
void one_chat_cb(lv_event_t* e)
{
    lv_obj_t *target = lv_event_get_target(e);
    lv_obj_t *label = lv_obj_get_child(target,0);
    char *txt = lv_label_get_text(label);
    char buf[32];
    strcpy(buf,txt);
    printf("目前聊天好友:%s\n",txt);  // name:id

    char *name = strtok(buf,":");
    char *id_s = strtok(NULL,":");
    //当前聊天界面的好友id
    cur_friend_id = atoi(id_s);
    printf("friendid = %d\n",cur_friend_id);

    cont = lv_obj_create(chat_scr);
    // lv_obj_set_flex_flow(cont,LV_FLEX_FLOW_ROW_WRAP);
    lv_obj_set_size(cont, 600, 480);
    lv_obj_set_style_border_width(cont, 0, 0);
    lv_obj_set_style_pad_all(cont, 0, 0);

    //当前聊天的好友名称
    lv_obj_t *friend_name_cont = lv_obj_create(cont);
    lv_obj_set_size(friend_name_cont, 600, 30);
    lv_obj_set_style_border_width(friend_name_cont, 0, 0);
    lv_obj_set_style_pad_all(friend_name_cont, 0, 0);
    lv_obj_set_style_bg_color(friend_name_cont, lv_color_make(160,225 , 230), LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_align(friend_name_cont,LV_ALIGN_TOP_MID,0,0);

    lv_obj_t *friend_name_label = lv_label_create(friend_name_cont);
    lv_label_set_text(friend_name_label,buf);
    lv_obj_center(friend_name_label);


    //消息框空间
    msg_cont = lv_obj_create(cont);
    lv_obj_set_size(msg_cont, 600, 270);
    lv_obj_set_style_border_width(msg_cont, 0, 0);
    lv_obj_set_style_pad_all(msg_cont, 0, 0);
    lv_obj_set_style_bg_color(msg_cont, lv_color_make(160,225 , 253), LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_align(msg_cont,LV_ALIGN_TOP_MID,0,30);

    //刷新聊天框
    update_msg();

    //聊天输入框
    lv_obj_t *chat_cont = lv_obj_create(cont);
    lv_obj_set_size(chat_cont, 500, 180);
    lv_obj_set_style_border_width(chat_cont, 0, 0);
    lv_obj_set_style_pad_all(chat_cont, 0, 0);
    lv_obj_remove_style(chat_cont, NULL, LV_PART_SCROLLBAR);    //移除滚动条样式
    lv_obj_set_style_bg_color(chat_cont, lv_color_make(175, 235, 187), LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_align(chat_cont,LV_ALIGN_BOTTOM_LEFT,0,0);

    //文件传输按钮
    lv_obj_t *file_btn = lv_btn_create(chat_cont);
    lv_obj_set_size(file_btn,80,30);
    lv_obj_align(file_btn, LV_ALIGN_TOP_LEFT, 20, 0);
    lv_obj_set_style_radius(file_btn,10,0);
    lv_obj_t *file_label = lv_label_create(file_btn);
    lv_label_set_text(file_label,"file");
    lv_obj_center(file_label);


    //ta输入
    lv_obj_t *msg_ta = lv_textarea_create(chat_cont);
    lv_obj_set_size(msg_ta, 480, 130);
    lv_obj_align(msg_ta, LV_ALIGN_BOTTOM_MID, 0, -10);
    lv_obj_remove_style(msg_ta, NULL, LV_PART_SCROLLBAR);    //移除滚动条样式
    lv_textarea_set_placeholder_text(msg_ta, "");//占位符的内容
    lv_obj_add_event_cb(msg_ta, keyboard_event_cb, LV_EVENT_ALL,NULL);//键盘

    //键盘
    keyboard = lv_keyboard_create(lv_scr_act());
    lv_keyboard_set_textarea(keyboard, NULL);
    lv_obj_add_flag(keyboard, LV_OBJ_FLAG_HIDDEN);

    //发送按钮
    lv_obj_t *send_btn = lv_btn_create(cont);
    lv_obj_set_size(send_btn,80,50);
    lv_obj_align_to(send_btn,chat_cont,LV_ALIGN_OUT_RIGHT_MID,10,0);
    lv_obj_set_style_radius(send_btn,20,0);
    lv_obj_t *send_label = lv_label_create(send_btn);
    lv_label_set_text(send_label,"send");
    lv_obj_center(send_label);

    //文件的响应
    lv_obj_add_event_cb(file_btn,file_event_cb,LV_EVENT_CLICKED,(void *)msg_ta);
    //发送的响应
    lv_obj_add_event_cb(send_btn,send_event_cb,LV_EVENT_CLICKED,(void *)msg_ta);
}

//动态刷新好友列表
void update_list(void*arg)
{
    lv_obj_t *type_list = (lv_obj_t *)arg;
    usleep(1000);
    while(1)
    {
        printf("cur_friend_num = %d ,好友列表\n",cur_friend_num);
        for(int i=0;i<cur_friend_num;i++)
        {   
            size_t buf_size = snprintf(NULL, 0, "%s:%d", cur_user_friend[i].username, cur_user_friend[i].id) + 1;
            char *buf = malloc(buf_size);
            sprintf(buf,"%s:%d",cur_user_friend[i].username,cur_user_friend[i].id);
            lv_obj_t *btn = lv_list_add_btn(type_list,NULL,buf);

            lv_obj_add_event_cb(btn,one_chat_cb,LV_EVENT_CLICKED,NULL);
        }
        sem_wait(&friend_list_update);
        lv_obj_clean(type_list);
    }
}

//发起请求从服务器获得好友数据
void get_friend_from_server(void)
{
    char buf[32];
    sprintf(buf,"-1:0:0");
    //发送获取好友请求
    write(comfd,buf,strlen(buf));
}

//聊天主界面
void qq_ui_init(void)
{
    if(com_flag == 0)
    {
        //聊天端口
        srvAddr.sin_port =htons(MSG_PORT);
        if(connect(comfd,(struct sockaddr*)&srvAddr,sizeof(srvAddr)) == 0)
        {
            printf("连接成功\n");
        }

        //发送获得好友数据信号
        get_friend_from_server();

        //若私聊对端不存在，服务器将发送一个OOB数据过来提醒
        signal(SIGURG,recvOOB);
        fcntl(comfd,F_SETOWN,getpid());

        //动态刷新当前用户的好友列表
        pthread_t tid1;
        pthread_create(&tid1,NULL,refresh_friend_list,NULL);

        //接收其他客户端的消息
        pthread_t tid2;
        pthread_create(&tid2,NULL,recvMsg,NULL);

        //动态刷新当前客户端的本地消息记录
        pthread_t tid3;
        pthread_create(&tid3,NULL,refresh_chat_log,NULL);

        //初始化信号量
        sem_init(&logs_update,0,0);
        com_flag = 1;
    }

    /*-----1.QQ界面-----*/
    lv_obj_t *qq_screen = lv_obj_create(lv_scr_act());
    lv_obj_set_size(qq_screen,800,480);
    lv_obj_set_style_border_width(qq_screen, 0, 0);
    lv_obj_set_style_pad_all(qq_screen, 0, 0);

    //添加好友的按钮
    lv_obj_t *Add_btn = lv_btn_create(qq_screen);
    lv_obj_set_size(Add_btn,200,50);
    lv_obj_set_align(Add_btn, LV_ALIGN_TOP_LEFT);

    lv_obj_t *Add_label = lv_label_create(Add_btn);
    lv_obj_center(Add_label);
    lv_label_set_text(Add_label,"ADD");
    lv_obj_set_style_text_font(Add_label,&lv_font_montserrat_20,0);

    // 好友列表
    lv_obj_t *type_list = lv_list_create(qq_screen);
    lv_obj_set_size(type_list,200,430);
    lv_obj_set_align(type_list, LV_ALIGN_BOTTOM_LEFT);

    //聊天框空间
    chat_scr = lv_obj_create(qq_screen);
    lv_obj_set_size(chat_scr,600,480);
    lv_obj_set_align(chat_scr, LV_ALIGN_TOP_RIGHT);
    lv_obj_set_style_border_width(chat_scr, 0, 0);
    lv_obj_set_style_pad_all(chat_scr, 0, 0);
    //    背景
    lv_obj_t *img = lv_img_create(chat_scr);
    lv_obj_set_style_border_width(img, 0, 0);
    lv_obj_set_style_pad_all(img, 0, 0);
    //    设置图片源
    LV_IMG_DECLARE(chat_bg);
    lv_img_set_src(img,&chat_bg);
    lv_obj_set_size(img,600,480);


    if(listflag == 0)
    {
        sem_init(&friend_list_update,0,0);
        //动态刷新好友列表
        pthread_t tidlist;
        pthread_create(&tidlist,NULL,update_list,(void *)type_list);
    }
    lv_obj_add_event_cb(Add_btn,add_friend_windows,LV_EVENT_CLICKED,NULL);


}

//本地创建文件
void file_creat(void)
{
    //对话记录
    int fd = open("chatlog.txt", O_WRONLY | O_CREAT | O_APPEND, 0644);  // 0644 = rw-r--r--

    if (fd == -1) {
        perror("open 失败");
        return 1;
    }
    close(fd);

    //好友文件
    int fd1 = open("friend.txt", O_WRONLY | O_CREAT | O_APPEND, 0644);  // 0644 = rw-r--r--

    if (fd1 == -1) {
        perror("open 失败");
        return 1;
    }
    close(fd1);
}

//登录按钮的回调
void login_btn_event_cb(lv_event_t *e)
{
    //文件准备
    file_creat();

    lv_obj_t *target = lv_event_get_target(e);
    Login_Data *login_data = (Login_Data*)lv_event_get_user_data(e);
    if(login_data == NULL)
    {
        printf("Error:selete_data is NULL\n");
        return;
    }
    char *userid = lv_textarea_get_text(login_data->username_ta);
    char *password = lv_textarea_get_text(login_data->password_ta);

    if(strlen(userid) == 0 || strlen(password)==0)
    {
        lv_obj_t * mbox = lv_msgbox_create(NULL, "error", "input not null", NULL, true);
        lv_obj_center(mbox);
        return;
    }

    char msg[32];
    bzero(msg,32);
    int login_flag = 0;
    //封装登录信息
    log_info info;
    info.id = atoi(userid);
    strcpy(info.logmsg,"in");
    strcpy(info.password,password);

    printf("logfd:info:%d\n",info.id);
    //发送登录请求
    sendto(logfd, &info, sizeof(info), 0, (struct sockaddr *)&srvAddr, sizeof(srvAddr));

    //接收响应
    recvfrom(logfd,msg,32,0,NULL,NULL);
    char *buf = strtok(msg,":");
    if(strcmp(buf,"success") == 0)
    {
        // printf("login success\n");

        login_flag=1;
        char *username = strtok(NULL,":");
        //记录当前客户端的账户
        cur_user.id = info.id;
        strcpy(cur_user.username,username);
        strcpy(cur_user.password,info.password);
        printf("cur_username:%s\n",cur_user.username);


        //进入登入界面
        qq_ui_init();
    }
    else if(strcmp(buf,"fail") == 0)
    {
        printf("login fail\n");
        //账户密码不正确
        // return ;
    }
    else if(strcmp(buf,"fail1") == 0)
    {
        //账户已在线，无法登录
        printf("账户在线\n");
        static const char *msgbtn[] = {" "," ","OK",""};
        lv_obj_t *msgbox = lv_msgbox_create(lv_scr_act(),LV_SYMBOL_WARNING"Notice"," The account is online.",msgbtn,true);
        lv_obj_set_size(msgbox,350,130);
        lv_obj_align(msgbox,LV_ALIGN_CENTER,0,0);
        lv_obj_t* btn = lv_msgbox_get_btns(msgbox);
        lv_obj_set_style_bg_opa(btn, 0, LV_PART_ITEMS);    //背景透明
        lv_obj_set_style_shadow_width(btn, 0, LV_PART_ITEMS);    //去除阴影
        lv_obj_set_style_text_color(btn, lv_color_hex(0x0000ff),LV_PART_ITEMS);    //字体颜色
        lv_obj_add_event_cb(msgbox, event_cb_msgbox, LV_EVENT_PRESSED,NULL);
        login_flag == 1;
    }

    // if(tmp != NULL)
    // {
    //     if(strcmp(tmp->password,password) == 0)
    //     {
    //         if((strcmp(flag,"Admin login") ==0) && (tmp->identity == 0))
    //         {
    //             // printf("amdin login success\n");
    //             login_flag=1;
    //             cur_login_user_info(tmp);
    //             log_add(LOG_LOGOUT,cur_user.username,cur_user.identity,"Login successful");
    //             admin_ui_init();
    //         }
    //         else if((strcmp(flag,"User login") ==0) && (tmp->identity > 0))
    //         {
    //             // printf("user login success\n");
    //             login_flag=1;
    //             cur_login_user_info(tmp);
    //             log_add(LOG_LOGOUT,cur_user.username,cur_user.identity,"Login successful");
    //             user_ui_init();
    //         }
    //     }
    // }
    //设置弹窗
    if(login_flag == 0)
    {
        static const char *msgbtn[] = {" "," ","OK",""};
        lv_obj_t *msgbox = lv_msgbox_create(lv_scr_act(),LV_SYMBOL_WARNING"Notice"," Incorrect input of account or password.",msgbtn,true);
        lv_obj_set_size(msgbox,350,130);
        lv_obj_align(msgbox,LV_ALIGN_CENTER,0,0);
        lv_obj_t* btn = lv_msgbox_get_btns(msgbox);
        lv_obj_set_style_bg_opa(btn, 0, LV_PART_ITEMS);    //背景透明
        lv_obj_set_style_shadow_width(btn, 0, LV_PART_ITEMS);    //去除阴影
        lv_obj_set_style_text_color(btn, lv_color_hex(0x0000ff),LV_PART_ITEMS);    //字体颜色
        lv_obj_add_event_cb(msgbox, event_cb_msgbox, LV_EVENT_PRESSED,NULL);
    }
}

//注册的事件
void register_event_cb(lv_event_t *e)
{
    lv_obj_t *target = lv_event_get_target(e);
    UserData *user_data = (UserData*)lv_event_get_user_data(e);
    if(user_data == NULL)
    {
        printf("Error:user_data is NULL\n");
        return;
    }
    char *user_id = lv_textarea_get_text(user_data->userid_ta);

    int userid = atoi(user_id);

    const char *username = lv_textarea_get_text(user_data->username_ta);
    char *password = lv_textarea_get_text(user_data->password_ta);
    char *password_twice = lv_textarea_get_text(user_data->password_ta2);

    static const char *msgbtn[] = {" "," ","OK",""};

    if(strcmp(password,password_twice) != 0)  //客户端自己检查两次密码是否一致
    {
        printf("twice password error\n");
        lv_obj_t *msgbox = lv_msgbox_create(lv_scr_act(),LV_SYMBOL_WARNING"Notice","The second password is inconsistent with the first one.",msgbtn,true);
        lv_obj_set_size(msgbox,350,150);
        lv_obj_align(msgbox,LV_ALIGN_CENTER,0,0);
        lv_obj_t* btn = lv_msgbox_get_btns(msgbox);
        lv_obj_set_style_bg_opa(btn, 0, LV_PART_ITEMS);    //背景透明
        lv_obj_set_style_shadow_width(btn, 0, LV_PART_ITEMS);    //去除阴影
        lv_obj_set_style_text_color(btn, lv_color_hex(0x0000ff),LV_PART_ITEMS);    //字体颜色
        lv_obj_add_event_cb(msgbox, event_cb_msgbox, LV_EVENT_PRESSED,NULL);
    }else{
        if(userid == 0)
        {
            lv_obj_t *msgbox = lv_msgbox_create(lv_scr_act(),LV_SYMBOL_WARNING"Notice","This ID is a system ID and cannot be created.",msgbtn,true);
            lv_obj_set_size(msgbox,350,150);
            lv_obj_align(msgbox,LV_ALIGN_CENTER,0,0);
            lv_obj_t* btn = lv_msgbox_get_btns(msgbox);
            lv_obj_set_style_bg_opa(btn, 0, LV_PART_ITEMS);    //背景透明
            lv_obj_set_style_shadow_width(btn, 0, LV_PART_ITEMS);    //去除阴影
            lv_obj_set_style_text_color(btn, lv_color_hex(0x0000ff),LV_PART_ITEMS);    //字体颜色
            lv_obj_add_event_cb(msgbox, event_cb_msgbox, LV_EVENT_PRESSED,NULL);
            return;
        }

        log_info info;
        strcpy(info.logmsg,"regist");    //注册信息
        info.id = (unsigned int)userid;  //用户id
        strcpy(info.username,username);  //用户名
        strcpy(info.password,password);  //密码

        char msg[32];
        bzero(msg,32);
        //发送注册请求
        sendto(logfd, &info, sizeof(info), 0, (struct sockaddr *)&srvAddr, sizeof(srvAddr));
        
        //接收响应消息
        recvfrom(logfd,msg,32,0,NULL,NULL);
        if(strcmp(msg,"regist success")==0)
        {
            //注册成功
            printf("%s\n",msg);
            lv_obj_t *msgbox = lv_msgbox_create(lv_scr_act(),LV_SYMBOL_WARNING"Notice"," register success.\n 2 seconds later, automatically return to the previous interface. ",msgbtn,true);
            lv_obj_set_size(msgbox,350,150);
            lv_obj_align(msgbox,LV_ALIGN_CENTER,0,0);
            lv_obj_t* btn = lv_msgbox_get_btns(msgbox);
            lv_obj_set_style_bg_opa(btn, 0, LV_PART_ITEMS);    //背景透明
            lv_obj_set_style_shadow_width(btn, 0, LV_PART_ITEMS);    //去除阴影
            lv_obj_set_style_text_color(btn, lv_color_hex(0x0000ff),LV_PART_ITEMS);    //字体颜色
            //返回登录界面
            Login_screen();

        }else if(strcmp(msg,"regist fail") == 0)
        {
            //注册失败
            printf("%s\n",msg);
            printf("The account already exists.\n");
            lv_obj_t *msgbox = lv_msgbox_create(lv_scr_act(),LV_SYMBOL_WARNING"Notice"," The account already exists.",msgbtn,true);
            lv_obj_set_size(msgbox,350,130);
            lv_obj_align(msgbox,LV_ALIGN_CENTER,0,0);
            lv_obj_t* btn = lv_msgbox_get_btns(msgbox);
            lv_obj_set_style_bg_opa(btn, 0, LV_PART_ITEMS);    //背景透明
            lv_obj_set_style_shadow_width(btn, 0, LV_PART_ITEMS);    //去除阴影
            lv_obj_set_style_text_color(btn, lv_color_hex(0x0000ff),LV_PART_ITEMS);    //字体颜色
            lv_obj_add_event_cb(msgbox, event_cb_msgbox, LV_EVENT_PRESSED,NULL);
            return ;
        }
    }

}

//注册界面
void register_ui_event_cb(lv_event_t *e)
{

    lv_obj_t *target = lv_event_get_target(e);

    /*------1.注册界面------*/
    lv_obj_t *register_screen = lv_obj_create(lv_scr_act());
    lv_obj_set_size(register_screen,800,480);
    lv_obj_set_style_border_width(register_screen, 0, 0);
    lv_obj_set_style_pad_all(register_screen, 0, 0);
    /*------2.背景图片------*/
    lv_obj_t *Login_bg_img = lv_img_create(register_screen);
    //    设置图片源
    LV_IMG_DECLARE(login_bg);
    lv_img_set_src(Login_bg_img,&login_bg);
    lv_obj_set_size(Login_bg_img,800,480);

    /*------3.文本框:账号、密码、再次输入密码-----*/
    //    3.1账户
    lv_obj_t *userid_ta = lv_textarea_create(register_screen);
    lv_obj_set_size(userid_ta, 300, 40);
    lv_obj_align(userid_ta, LV_ALIGN_TOP_MID, 0, 50);
    lv_obj_remove_style(userid_ta, NULL, LV_PART_SCROLLBAR);    //移除滚动条样式
    lv_textarea_set_placeholder_text(userid_ta, "userID");//占位符的内容
    lv_obj_add_event_cb(userid_ta, keyboard_event_cb, LV_EVENT_ALL,NULL);//键盘

    //    3.1用户名
    lv_obj_t *username_ta = lv_textarea_create(register_screen);
    lv_obj_set_size(username_ta, 300, 40);
    // lv_obj_align(username_ta, LV_ALIGN_TOP_MID, 0, 50);
    lv_obj_align_to(username_ta,userid_ta,LV_ALIGN_OUT_BOTTOM_MID, 0, 40);
    lv_obj_remove_style(username_ta, NULL, LV_PART_SCROLLBAR);    //移除滚动条样式
    lv_textarea_set_placeholder_text(username_ta, "username");//占位符的内容
    lv_obj_add_event_cb(username_ta, keyboard_event_cb, LV_EVENT_ALL,NULL);//键盘

    //   3.2密码
    lv_obj_t *password_ta = lv_textarea_create(register_screen);
    lv_obj_set_size(password_ta, 300, 40);
    lv_obj_align_to(password_ta,username_ta,LV_ALIGN_OUT_BOTTOM_MID, 0, 40);
    lv_obj_remove_style(password_ta, NULL, LV_PART_SCROLLBAR);
    lv_textarea_set_password_mode(password_ta, true);//设置密码模式，输入以*代替
    lv_textarea_set_placeholder_text(password_ta, "password");
    lv_obj_add_event_cb(password_ta, keyboard_event_cb, LV_EVENT_ALL,NULL);

    //   3.3 再次输入密码
    lv_obj_t *password_ta2 = lv_textarea_create(register_screen);
    lv_obj_set_size(password_ta2, 300, 40);
    lv_obj_align_to(password_ta2,password_ta,LV_ALIGN_OUT_BOTTOM_MID, 0, 40);
    lv_obj_remove_style(password_ta2, NULL, LV_PART_SCROLLBAR);
    lv_textarea_set_password_mode(password_ta2, true);//设置密码模式，输入以*代替
    lv_textarea_set_placeholder_text(password_ta2, "twice password");
    lv_obj_add_event_cb(password_ta2, keyboard_event_cb, LV_EVENT_ALL,NULL);

    //  3.4创建user标签
    lv_obj_t *label_user = lv_label_create(register_screen);
    lv_label_set_text(label_user, "");
    lv_obj_set_style_text_font(label_user, &lv_font_montserrat_20, LV_PART_MAIN);
    lv_obj_align_to(label_user,username_ta, LV_ALIGN_OUT_RIGHT_MID,30,0);
    //  3.5创建password标签
    lv_obj_t *label_password = lv_label_create(register_screen);
    lv_label_set_text(label_password, "");
    lv_obj_set_style_text_font(label_password, &lv_font_montserrat_20, LV_PART_MAIN);
    lv_obj_align_to(label_password,password_ta, LV_ALIGN_OUT_RIGHT_MID,30,0);

    // 4.注册按钮
    lv_obj_t *Register_btn = lv_btn_create(register_screen);
    lv_obj_set_size(Register_btn,100,50);
    lv_obj_align_to(Register_btn,password_ta2, LV_ALIGN_OUT_BOTTOM_MID,0,40);

    lv_obj_t *Register_label = lv_label_create(Register_btn);
    lv_obj_center(Register_label);
    lv_label_set_text(Register_label,"Register");
    lv_obj_set_style_text_font(Register_label,&lv_font_montserrat_20,0);

    UserData *user_data = malloc(sizeof(UserData));
    if (user_data == NULL) {
        printf("Memory allocation failed\n");
        return;
    }
    user_data->userid_ta = userid_ta;
    user_data->username_ta = username_ta;
    user_data->password_ta = password_ta;
    user_data->password_ta2 = password_ta2;
    lv_obj_add_event_cb(Register_btn,register_event_cb,LV_EVENT_CLICKED,(void *)user_data);

    //键盘
    keyboard = lv_keyboard_create(lv_scr_act());
    lv_keyboard_set_textarea(keyboard, NULL);
    lv_obj_add_flag(keyboard, LV_OBJ_FLAG_HIDDEN);

    //5.退出
    // lv_obj_t *quit_btn = lv_btn_create(register_screen);
    // lv_obj_set_size(quit_btn,80,50);
    // lv_obj_t *quit_label = lv_label_create(quit_btn);

    // lv_obj_center(quit_label);
    // lv_label_set_text(quit_label,LV_SYMBOL_LEFT);
    // lv_obj_set_style_text_font(quit_label,&lv_font_montserrat_20,0);
    
    // lv_obj_add_event_cb(quit_btn,_cb,LV_EVENT_CLICKED,quit_btn);
}

//登录界面
void Login_screen(void)
{   
    logfd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
    comfd = socket(AF_INET,SOCK_STREAM,0);

    //确定服务器地址
    srvAddr.sin_family = AF_INET;
    srvAddr.sin_addr.s_addr = inet_addr("192.168.3.211");

    //登入登出注册
    srvAddr.sin_port = htons(Login_Out_PORT);
    bind(logfd,(struct sockaddr *)&srvAddr,sizeof(srvAddr));
    //初始化信号量
    sem_init(&cur_user_friend_update,0,0);


    /*-----1.登录界面-----*/
    lv_obj_t *login_screen = lv_obj_create(lv_scr_act());
    lv_obj_set_size(login_screen,800,480);
    lv_obj_set_style_border_width(login_screen, 0, 0);
    lv_obj_set_style_pad_all(login_screen, 0, 0);

    /*------2.背景图片------*/
    lv_obj_t *Login_bg_img = lv_img_create(login_screen);
    //    设置图片源
    LV_IMG_DECLARE(login_bg);
    lv_img_set_src(Login_bg_img,&login_bg);
    lv_obj_set_size(Login_bg_img,800,480);

    /*-------3.文本框(账号密码)--------*/
    //    3.1账号
    lv_obj_t *username_ta = lv_textarea_create(login_screen);
    lv_obj_set_size(username_ta, 300, 40);
    lv_obj_align(username_ta, LV_ALIGN_TOP_MID, 0, 50);
    lv_obj_remove_style(username_ta, NULL, LV_PART_SCROLLBAR);    //移除滚动条样式
    lv_textarea_set_placeholder_text(username_ta, "username");//占位符的内容
    lv_obj_add_event_cb(username_ta, keyboard_event_cb, LV_EVENT_ALL,NULL);//键盘
    //   3.2密码
    lv_obj_t *password_ta = lv_textarea_create(login_screen);
    lv_obj_set_size(password_ta, 300, 40);
    lv_obj_align_to(password_ta,username_ta,LV_ALIGN_OUT_BOTTOM_MID, 0, 40);
    lv_obj_remove_style(password_ta, NULL, LV_PART_SCROLLBAR);
    lv_textarea_set_password_mode(password_ta, true);//设置密码模式，输入以*代替
    lv_textarea_set_placeholder_text(password_ta, "password");
    lv_obj_add_event_cb(password_ta, keyboard_event_cb, LV_EVENT_ALL,NULL);

    //  3.3创建user标签
    lv_obj_t *label_user = lv_label_create(login_screen);
    lv_label_set_text(label_user, "");
    lv_obj_set_style_text_font(label_user, &lv_font_montserrat_20, LV_PART_MAIN);
    lv_obj_align_to(label_user,username_ta, LV_ALIGN_OUT_RIGHT_MID,30,0);
    //  3.4创建password标签
    lv_obj_t *label_password = lv_label_create(login_screen);
    lv_label_set_text(label_password, "");
    lv_obj_set_style_text_font(label_password, &lv_font_montserrat_20, LV_PART_MAIN);
    lv_obj_align_to(label_password,password_ta, LV_ALIGN_OUT_RIGHT_MID,30,0);

    //  4.按钮:登录、注册
    // 登录
    lv_obj_t *Login_btn = lv_btn_create(login_screen);
    lv_obj_set_size(Login_btn,100,50);
    lv_obj_align_to(Login_btn,password_ta, LV_ALIGN_OUT_BOTTOM_MID,70,10);

    lv_obj_t *Login_label = lv_label_create(Login_btn);
    lv_obj_center(Login_label);
    lv_label_set_text(Login_label,"Login");
    lv_obj_set_style_text_font(Login_label,&lv_font_montserrat_20,0);

    //登录的回调
    Login_Data *login_data = malloc(sizeof(Login_Data));
    if(login_data == NULL)
    {
        printf("Memory allocation failed\n");
        return;
    }

    login_data->username_ta = username_ta;
    login_data->password_ta = password_ta;

    lv_obj_add_event_cb(Login_btn,login_btn_event_cb,LV_EVENT_CLICKED,(void *)login_data);

    //  注册
    lv_obj_t *Register_btn = lv_btn_create(login_screen);
    lv_obj_set_size(Register_btn,100,50);
    lv_obj_align_to(Register_btn,password_ta, LV_ALIGN_OUT_BOTTOM_MID,-70,10);

    lv_obj_t *Register_label = lv_label_create(Register_btn);
    lv_obj_center(Register_label);
    lv_label_set_text(Register_label,"Register");
    lv_obj_set_style_text_font(Register_label,&lv_font_montserrat_20,0);

    //注册的回调
    lv_obj_add_event_cb(Register_btn,register_ui_event_cb,LV_EVENT_CLICKED,NULL);


    //键盘
    keyboard = lv_keyboard_create(lv_scr_act());
    lv_keyboard_set_textarea(keyboard, NULL);
    lv_obj_add_flag(keyboard, LV_OBJ_FLAG_HIDDEN);

}